package com.whoyx.jiebing.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author stone
 */
@Slf4j
@Component
public class RemoteUtils {

    public static String sendPost(String url, Map<String, Object> paramsMap) {
        String result = null;
        try {
            String jsonString = new ObjectMapper().writeValueAsString(paramsMap);
            Map<String, String> headerMap = new HashMap<>();
            headerMap.put("Content-Type", "application/json;charset=utf8");
            result = sendPost(url, jsonString, headerMap);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("【REMOTE】--JSON转换失败--");
        }
        return result;
    }

    public static String sendPost(String url, Map<String, Object> paramsMap, Map<String, String> headerMap) {
        String result = null;
        try {
            String jsonString = new ObjectMapper().writeValueAsString(paramsMap);
            headerMap.put("Content-Type", "application/json;charset=utf8");
            result = sendPost(url, jsonString, headerMap);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            log.error("【REMOTE】--JSON转换失败--");
        }
        return result;
    }

    public static String sendPost(String url, String paramsJson, Map<String, String> headerMap) {
        String result = null;
        try {
            log.info("【REMOTE】--开始-----------------");
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpPost httpPost = new HttpPost(url);
            headerMap.forEach(httpPost::addHeader);
            httpPost.setEntity(new StringEntity(paramsJson, ContentType.APPLICATION_JSON));
            httpPost.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setSocketTimeout(5000)
                    .setRedirectsEnabled(false).build());
            log.info("【REMOTE】--请求--, httpPost :\n {} \nparams :\n {}", httpPost, paramsJson);
            result = execute(httpClient, httpPost);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【REMOTE】--失败--");
        }
        log.info("【REMOTE】--结束-----------------");
        return result;
    }

    public static String sentUrlencodedPost(String url, Map<String, String> paramsMap) {
        String result = null;
        List<BasicNameValuePair> params = new ArrayList<>();
        paramsMap.forEach((key, value) -> params.add(new BasicNameValuePair(key, value)));
        result = sendUrlencodedPost(url, params);
        return result;
    }

    public static String sendUrlencodedPost(String url, List<BasicNameValuePair> params) {
        String result = null;
        try {
            log.info("【REMOTE】--开始-----------------");
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            httpPost.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setSocketTimeout(5000)
                    .setRedirectsEnabled(false).build());
            log.info("【REMOTE】--请求--, httpPost :\n {} \nparams :\n {}", httpPost, params);
            result = execute(httpClient, httpPost);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【REMOTE】--失败--");
        }
        log.info("【REMOTE】--结束-----------------");
        return result;
    }

    public static String sendGet(String baseUrl, Map<String, Object> paramsMap) {
        StringBuilder url = new StringBuilder(baseUrl);
        if (null != paramsMap) {
            url.append("?");
            paramsMap.forEach((key, value) -> url.append(key).append("=").append(value).append("&"));
            url.deleteCharAt(url.length() - 1);
        }
        return sendGet(url.toString());
    }

    public static String sendGet(String baseUrl, Map<String, Object> paramsMap, Map<String, String> headerMap) {
        StringBuilder url = new StringBuilder(baseUrl);
        if (null != paramsMap) {
            url.append("?");
            paramsMap.forEach((key, value) -> url.append(key).append("=").append(value).append("&"));
            url.deleteCharAt(url.length() - 1);
        }
        String result = null;
        try {
            log.info("【REMOTE】--开始-----------------");
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpGet httpGet = new HttpGet(String.valueOf(url));
            headerMap.forEach(httpGet::addHeader);
            httpGet.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setSocketTimeout(5000)
                    .setRedirectsEnabled(false).build());
            result = execute(httpClient, httpGet);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【REMOTE】--失败--");
        }
        log.info("【REMOTE】--结束-----------------");
        return result;

    }

    public static String sendDelete(String baseUrl,Map<String,String> headerMap){
        String result = null;
        try {
            log.info("【REMOTE】--开始-----------------");
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpDelete httpDelete = new HttpDelete(String.valueOf(baseUrl));
            headerMap.forEach(httpDelete::addHeader);
            httpDelete.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setSocketTimeout(5000)
                    .setRedirectsEnabled(false).build());
            result = execute(httpClient, httpDelete);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【REMOTE】--失败--");
        }
        log.info("【REMOTE】--结束-----------------");
        return result;
    }

    public static String sendGet(String url) {
        String result = null;
        try {
            log.info("【REMOTE】--开始-----------------");
            CloseableHttpClient httpClient = HttpClientBuilder.create().build();
            HttpGet httpGet = new HttpGet(url);
            httpGet.setConfig(RequestConfig.custom()
                    .setConnectTimeout(5000)
                    .setConnectionRequestTimeout(5000)
                    .setSocketTimeout(5000)
                    .setRedirectsEnabled(false).build());
            result = execute(httpClient, httpGet);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("【REMOTE】--失败--");
        }
        log.info("【REMOTE】--结束-----------------");
        return result;
    }


    private static String execute(CloseableHttpClient httpClient, HttpRequestBase request) {
        String result = null;
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(request);
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                log.info("【REMOTE】--成功--, response :\n {}", result);
                EntityUtils.consume(entity);
            } else {
                HttpEntity entity = response.getEntity();
                result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                log.info("【REMOTE】--失败--, response :\n {}", result);
                EntityUtils.consume(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != httpClient) {
                    httpClient.close();
                }
                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

}
